# coding:utf-8
from pathlib import Path
from typing import List, Any

from PyQt6.QtCore import pyqtSignal, QThreadPool
from PyQt6.QtWidgets import QHBoxLayout, QFileDialog
from pdf2docx import Converter
from qfluentwidgets import SimpleCardWidget, BodyLabel, TransparentToolButton, FluentIcon as FIF, CompactSpinBox, \
    HorizontalSeparator, LineEdit, PrimaryPushButton, PushButton, InfoBar, setFont

from common import OfficeIcon
from components import BaseScrollArea


def __pdf2docx(
        pdf_file: str,
        save_path: str,
        password: str = None,
        start: int = 0,
        end: int = None
):
    """
    将 PDF 文件转换为 Word 文件
    :param pdf_file:
    :param save_path:
    :param password:
    :param start:
    :param end:
    :return:
    """
    print(pdf_file, save_path, password, start, end)
    if isinstance(pdf_file, str):
        pdf_file = Path(pdf_file)
    if isinstance(save_path, str):
        save_path = Path(save_path)
    if not save_path:
        docx_filename = pdf_file.with_suffix('.docx')
    else:
        docx_filename = save_path.joinpath(pdf_file.name).with_suffix('.docx')
    save_path.mkdir(parents=True, exist_ok=True)
    converter = Converter(pdf_file.as_posix(), password=password)
    converter.convert(docx_filename=docx_filename.as_posix(), start=start, end=end)
    converter.close()


def pdf_to_word(params: List[dict]):
    """
    将 PDF 文件转换为 Word 文件
    :arg params: [
        {
            'pdf_file': '文件路径',
            'save_path': '保存路径',
            'start': 开始页码,
            'end': 结束页码
            'password': '密码'
        }
    ]
    :return:
    """
    thread_pool = QThreadPool.globalInstance()
    thread_pool.setMaxThreadCount(4)
    for param in params:
        thread_pool.start(lambda pm=param: __pdf2docx(**pm))
    thread_pool.waitForDone()


class PdfItemCard(SimpleCardWidget):
    removed = pyqtSignal(SimpleCardWidget)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.horizontalLayout = QHBoxLayout(self)
        self.pdfLabel = BodyLabel(self)
        self.startSpinBox = CompactSpinBox(self)
        self.endSpinBox = CompactSpinBox(self)
        self.passwordLineEdit = LineEdit(self)
        self.deleteButton = TransparentToolButton(FIF.CLOSE, self)
        self.__initWidget()

    def __initWidget(self):
        self.setFixedHeight(60)
        self.startSpinBox.setRange(0, 1000000)
        self.endSpinBox.setRange(0, 1000000)
        self.startSpinBox.setPrefix('开始页码:  ')
        self.endSpinBox.setPrefix('结束页码:  ')
        self.passwordLineEdit.setPlaceholderText('密码')

        self.horizontalLayout.addWidget(self.pdfLabel)
        self.horizontalLayout.addStretch(1)
        self.horizontalLayout.addWidget(self.startSpinBox)
        sep = HorizontalSeparator(self)
        sep.setFixedWidth(20)
        self.horizontalLayout.addWidget(sep)
        self.horizontalLayout.addWidget(self.endSpinBox)
        self.horizontalLayout.addSpacing(40)
        self.horizontalLayout.addWidget(self.passwordLineEdit)
        self.horizontalLayout.addSpacing(40)
        self.horizontalLayout.addWidget(self.deleteButton)

        self.deleteButton.clicked.connect(lambda: self.removed.emit(self))

    def setText(self, text: str):
        self.pdfLabel.setText(text)

    def getParams(self):
        password = self.passwordLineEdit.text()
        start = self.startSpinBox.value()
        end = self.endSpinBox.value()
        if not password:
            password = None
        if end == 0:
            end = None

        return {
            'pdf_file': self.pdfLabel.text(),
            'password': password,
            'start': start,
            'end': end
        }


class PDFToWordView(BaseScrollArea):
    title = 'PDF 转 Word'
    description = '将 PDF 文件转换为 Word 文件'
    icon = OfficeIcon.WORD4
    object_name = 'PDFToWordView'

    def __init__(self, parent=None):
        super().__init__(parent)
        self.titleLabel = BodyLabel('PDF 转 Word(不支持扫描件)', self)
        self.horizontalLayout = QHBoxLayout()
        self.addPdfButton = PrimaryPushButton(FIF.ADD, '添加 PDF', self)
        self.folderButton = PushButton(FIF.FOLDER_ADD, '选择文件夹', self)
        self.savePathLineEdit = LineEdit(self)
        self.startButton = PrimaryPushButton(FIF.PLAY, '开始转换', self)

        self.cards = []
        self.__initWidget()

    def __initWidget(self):
        setFont(self.titleLabel, 24)
        self.savePathLineEdit.setPlaceholderText('保存路径')
        self.savePathLineEdit.setReadOnly(True)

        self.horizontalLayout.addWidget(self.savePathLineEdit)
        self.horizontalLayout.addWidget(self.folderButton)
        self.horizontalLayout.addWidget(self.addPdfButton)
        self.horizontalLayout.addWidget(self.startButton)

        self.scrollLayout.addWidget(self.titleLabel)
        self.scrollLayout.addLayout(self.horizontalLayout)
        self.setReturnVisible(True)

        self.folderButton.clicked.connect(self.selectFolder)
        self.addPdfButton.clicked.connect(self.addPdf)
        self.startButton.clicked.connect(self.startConvert)

    def startConvert(self):
        params = []
        for card in self.cards:
            pm = card.getParams()
            pm.update({'save_path': self.savePathLineEdit.text()})
            params.append(pm)
        if not params:
            return
        self.setToolTipContent('正在转换 PDF 文件，请稍候...')
        self.load(pdf_to_word, params)

    def selectFolder(self):
        folder = QFileDialog.getExistingDirectory(self, '选择文件夹', self.savePathLineEdit.text())
        self.savePathLineEdit.setText(folder)

    def addPdf(self):
        file_names, _ = QFileDialog.getOpenFileNames(self, '选择文件', '', 'PDF 文件 (*.pdf)')
        if not file_names:
            return
        for file_name in file_names:
            self.addPdfItem(file_name)

    def addPdfItem(self, pdf_file: str):
        card = PdfItemCard(self)
        card.setText(pdf_file)
        card.removed.connect(self.removePdfItem)
        self.cards.append(card)
        self.scrollLayout.addWidget(card)

    def removePdfItem(self, card: PdfItemCard):
        self.cards.remove(card)
        self.scrollLayout.removeWidget(card)
        card.deleteLater()

    def onFuncSuccess(self, result: Any):
        InfoBar.success('', 'PDF 转换成功', isClosable=True, duration=3000, parent=self.window())
